package cn.gjculture.shopping.api.service.impl;

import cn.gjculture.shopping.api.entity.Customer;
import cn.gjculture.shopping.api.entity.wx.*;
import cn.gjculture.shopping.api.service.PassiveMessageService;
import cn.gjculture.shopping.api.service.WXService;
import cn.gjculture.shopping.api.util.MessageHandlerUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class WXServiceImpl implements WXService {

    @Autowired
    PassiveMessageService passiveMessageService;

    @Autowired
    WXProxy wxProxy;

    private Map<String, AccessToken> map=new  ConcurrentHashMap<>(1);
    private static final String key="access_token";


    @Override
    public int sendServiceMessage(PicTxtMessage message, List<Customer> customers) {
        if(CollectionUtils.isEmpty(customers)|| message == null) return 0;
        for(int i=0;i<customers.size();i++){
            String openId=customers.get(i).getOpenid();
            String accessToken=this.getAccessToken();
            this.sendPicTxtMessage(openId,message,accessToken);
        }
        return customers.size();
    }

    @Override
    public boolean sendPicTxtMessage(String openId, PicTxtMessage message, String accessToken) {
        return wxProxy.sendPicTxtMessage(openId,message,accessToken);
    }

    @Override
    public String getAutoMessage(Map<String, String> map) {
        String message;
        //得到消息类型
        String msgType = map.get("MsgType");
        System.out.println("MsgType:" + msgType);
        //消息类型
        MessageType messageEnumType = MessageType.valueOf(MessageType.class, msgType.toUpperCase());
        switch (messageEnumType) {
            case TEXT:
                //处理文本消息
                message = handleOtherMessage(map);
                break;
            case IMAGE:
                //处理图片消息
                message = handleOtherMessage(map);
                break;
            case VOICE:
                //处理语音消息
                message = handleOtherMessage(map);
                break;
            case VIDEO:
                //处理视频消息
                message = handleOtherMessage(map);
                break;
            case SHORTVIDEO:
                //处理小视频消息
                message = handleOtherMessage(map);
                break;
            case LOCATION:
                //处理位置消息
                message = handleOtherMessage(map);
                break;
            case LINK:
                //处理链接消息
                message = handleOtherMessage(map);
                break;
            case EVENT:
                message = handleEventMessage(map);
                break;
            default: message = handleOtherMessage(map);
                break;
        }
        //返回响应消息
        return message;
    }

    @Override
    public List<String> getAllOpenId(String accessToken) {
        long start=System.currentTimeMillis()+600000;
        log.info("get all openid...");
        List<String> openIds=new ArrayList<>();
        JSONObject jsonObject=wxProxy.getOpenId(accessToken,null);
        openIds.addAll(jsonObject.getJSONObject("data").getJSONArray("openid").toJavaList(String.class));
        int total=jsonObject.getIntValue("total");
        while (openIds.size()<total){
            jsonObject=wxProxy.getOpenId(accessToken,jsonObject.getString("next_openid"));
            openIds.addAll(jsonObject.getJSONObject("data").getJSONArray("openid").toJavaList(String.class));
            if(start<System.currentTimeMillis()){
                return openIds;
            }
        }
        log.info("get all openid total:{}",openIds.size());
        return openIds;
    }

    private String handleOtherMessage(Map<String, String> map) {
        PassiveMessage passiveMessage=passiveMessageService.queryValidPassiveMessage();
        if(passiveMessage==null || CollectionUtils.isEmpty(passiveMessage.getMessages())) return "";
        return buildNewsMessage(map,passiveMessage.getMessages());
    }

    private String handleEventMessage(Map<String, String> map) {
        PassiveMessage passiveMessage=passiveMessageService.queryValidEventMessage();
        if(passiveMessage==null || CollectionUtils.isEmpty(passiveMessage.getMessages())) return "";
        if ("subscribe".equals(map.get("Event"))||"SCAN".equals(map.get("Event"))) {
            return buildNewsMessage(map, passiveMessage.getMessages());
        }
        return "";
    }

    private String buildNewsMessage(Map<String, String> map, List<PicTxtMessage> messages) {
        String fromUserName = map.get("FromUserName");
        String toUserName = map.get("ToUserName");
        StringBuilder itemContent=new StringBuilder();
        for(PicTxtMessage m: messages){
            NewsItem item = new NewsItem();
            item.Title = m.getTitle();
            item.Description = m.getDescription();
            item.PicUrl = m.getPicurl();
            item.Url = m.getUrl();
            String itemString = MessageHandlerUtil.buildSingleItem(item);
            itemContent.append(itemString);
        }
        String content = String.format("<xml>" +
                "<ToUserName><![CDATA[%s]]></ToUserName>" +
                "<FromUserName><![CDATA[%s]]></FromUserName>" +
                "<CreateTime>%s</CreateTime>" +
                "<MsgType><![CDATA[news]]></MsgType>" +
                "<ArticleCount>%s</ArticleCount>" +
                "<Articles>" + "%s" + "</Articles>" +
                "</xml> ", fromUserName, toUserName, System.currentTimeMillis(), messages.size(), itemContent.toString());
        return content;
    }



    @Override
    public String getAccessToken(){
        AccessToken accessToken=map.get(key);
        if(accessToken!=null&&accessToken.getExpire()>System.currentTimeMillis()){
            return accessToken.getToken();
        }else{
            String token=wxProxy.getAccessToken();
            accessToken=new AccessToken();
            accessToken.setToken(token);
            accessToken.setExpire(System.currentTimeMillis()+5500000);
            map.put(key,accessToken);
            return token;
        }
    }


}
